/*
 * Syntelos 'SX'
 * Copyright (C) 1998, 2007  John Pritchard.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 */
package syntelos.sx.methods.s;

import syntelos.sx.Response;
import syntelos.sx.Request;
import syntelos.sx.Server;
import syntelos.sx.Socket;

import alto.io.Output;
import alto.io.Principal;
import alto.io.Keys;
import alto.lang.Buffer;
import alto.lang.Type;
import alto.sec.x509.X509Certificate;

import java.security.cert.Certificate;


/**
 * Trace user certificate
 * 
 * @since 1.6
 */
public class Trace
    extends Abstract
{

    private final static java.lang.String Hex(java.math.BigInteger num){
        if (null == num)
            return "";
        else {
            byte[] bits = num.toByteArray();
            return alto.io.u.Hex.encode(bits);
        }
    }

    public final static void Trace(Certificate cert, alto.lang.buffer.OutputStream out)
        throws java.io.IOException
    {
        out.println("Certificate-Type: "+cert.getType());
        if (cert instanceof X509Certificate){
            X509Certificate x509cert = (X509Certificate)cert;
            out.println("Certificate-X509-Version: "+x509cert.getVersion());
            out.println("Certificate-X509-Serial: "+Hex(x509cert.getSerialNumber()));
            out.println("Certificate-X509-Subject: "+x509cert.getSubjectDN().getName());
            out.println("Certificate-X509-Issuer: "+x509cert.getIssuerDN().getName());
            out.println("Certificate-X509-SigAlg: "+x509cert.getSigAlgName());
        }
        else
            out.println("Certificate-Error: Unrecognized; "+cert.getClass().getName());
        //
        out.println();
    }


    public Trace(){
        super();
    }


    public void respond(Request req)
        throws java.io.IOException,
               java.lang.InterruptedException
    {
        Certificate[] chain = req.getSecureRemoteCertificates();
        if (null != chain){
            alto.lang.buffer.Abstract iob = this.getCreateBuffer();
            alto.lang.buffer.OutputStream bout = (alto.lang.buffer.OutputStream)iob.openOutput();
            for (int cc = 0, count = chain.length; cc < count; cc++){
                bout.println("Certificate: "+cc);
                Trace(chain[cc],bout);
            }
        }
        else if (this.isAuthenticated()){
            Principal.Actual principal = (Principal.Actual)req.getPrincipal();
            X509Certificate cert = principal.getCertificate("RSA");
            alto.lang.buffer.Abstract iob = this.getCreateBuffer();
            alto.lang.buffer.OutputStream bout = (alto.lang.buffer.OutputStream)iob.openOutput();
            bout.println("Certificate: 0");
            Trace(cert,bout);
        }
        else
            this.setStatusNoContent();
    }

}
